#define  PI 3.1415

vec2 fixuv(in vec2 uv) {
    vec2 p;
    p = (2.0 * uv - iResolution.xy) / min(iResolution.x, iResolution.y);

    p *= 8.;
    return p;
}

vec3 drawGrid(in vec2 p) {
    float f = floor(p.x) + floor(p.y);
    vec3 col = mix(vec3(0.75), vec3(0.3), smoothstep(0., 1., mod(f, 2.)));
    col = mix(col, vec3(1., 0., 0.), smoothstep(abs(p.x), abs(p.x), fwidth(p.x) * 2.));
    col = mix(col, vec3(0., 0., 1.), smoothstep(abs(p.y), abs(p.y), fwidth(p.y) * 2.));
    return col;
}

vec3 drawSegment(in vec2 p, in vec2 sp, in vec2 ep, in float w, in vec3 color, in vec3 col) {

    vec2 v1 = ep - sp;
    vec2 v2 = sp - ep;
    vec2 a1 = p - sp;
    vec2 a2 = p - ep;

    float theta = dot(v1, a1) / pow(length(v1), 2.);
    vec2 b = a1 - v1 * theta;

    if(dot(v1, a1) > 0. && dot(v2, a2) > 0.) {
        col = mix(col, color, smoothstep(w, w * 0.99, length(b)));
    }

    return col;
}

vec3 drawAngleSegment(in vec2 p, in vec2 sp, in float angle, in float len, in float w, in vec3 color, in vec3 col) {

    float radin = (PI / 180. * angle);
    vec2 ep = sp + vec2(cos(radin), sin(radin)) * len;
    col = drawSegment(p, sp, ep, w, color, col);

    return col;
}

vec3 drawPoint(in vec2 p, in vec2 pos, in float s, in vec3 color, in vec3 col) {

    col = mix(col, color, smoothstep(s, s * 0.99, length(pos - p)));

    return col;
}

vec3 vectorProjection(in vec2 p, in vec2 sp, in vec2 ep, in vec3 color, in vec3 col) {

    vec2 pos = fixuv(iMouse.xy);
    vec2 v = ep - sp;
    vec2 a = pos - sp;
    // 夹角
    float theta = dot(v, a) / pow(length(v), 2.);
    // 模长的位置
    vec2 e = sp + (v) * theta;

    float w = fwidth(p.x) * 2.;
    col = drawSegment(p, pos, e, w, color, col);

    // col = drawPoint(p, line1.xy + (v1) * theta, fwidth(p.x) * 5., vec3(0.98, 0, 0.49), col);
    // col = drawSegment(p, line1.xy + (v1) * theta, line1.xy, w * 1., vec3(0, 0.19, 0.2), col);
    // col = drawSegment(p, ep, pos, w * 1., vec3(0.245, 0.78, 1.), col);
    // col = drawSegment(p, line1.xy, pos, w * 1., vec3(0.15, 0, 0.49), col);
    // col = drawPoint(p, pos, fwidth(p.x) * 5., vec3(0.98, 0, 0.49), col);

    return col;
}

// 向量加法
vec3 vectorAdd(in vec2 p, in vec3 col) {

    vec4 line1 = vec4(0., 0.0, 10.0, 1.5);
    vec4 line2 = vec4(0., 0.0, 10.0, 1.5);
    vec4 line3 = vec4(0., 0., 3.0, 4.5);
    vec4 line4 = vec4(0., 0., 3.0, 4.5);

    line2.xy += mix(vec2(0.), vec2(line3.zw), abs(sin(iTime / 3.)));
    line2.zw += mix(vec2(0.), vec2(line3.zw), abs(sin(iTime / 3.)));

    line4.xy += mix(vec2(0.), vec2(line1.zw), abs(sin(iTime / 3.)));
    line4.zw += mix(vec2(0.), vec2(line1.zw), abs(sin(iTime / 3.)));

    col = drawSegment(p, line1.xy, line1.zw, fwidth(p.x) * 2., vec3(1., 0.4, 0.), col);
    col = drawSegment(p, line2.xy, line2.zw, fwidth(p.x) * 2., vec3(0.57, 1, 0), col);
    col = drawSegment(p, line3.xy, line3.zw, fwidth(p.x) * 2., vec3(1, 0.77, 0), col);
    col = drawSegment(p, line4.xy, line4.zw, fwidth(p.x) * 2., vec3(1, 0, 0.83), col);

   if(iMouse.x >0.) {

       col = vectorProjection(p, line1.xy, line1.zw, vec3(line1.xyz), col);
    col = vectorProjection(p, line2.xy, line2.zw, vec3(line2.xyz), col);
    col = vectorProjection(p, line3.xy, line3.zw, vec3(line3.xyz), col);
    col = vectorProjection(p, line4.xy, line4.zw, vec3(line4.xyz), col);
    }

    return col;
}

vec3 vectorMultiply(in vec2 p, in vec3 col) {

    vec2 sp = vec2(-6., -4.);
    sp *= abs(cos(iTime));
    float len = 3. + abs(sin(iTime)) * 4.;
    float angle = iTime * 10.;
    float w = fwidth(p.x);
    w = w + w * abs(sin(iTime * 3.)) * 5.;
    col = drawAngleSegment(p, sp, angle, len, w, vec3(1.0, .4, 0.8), col);

    if(iMouse.z > 0.0001) {

        float radin = (PI / 180. * angle);
        vec2 ep = sp + vec2(cos(radin), sin(radin)) * len;
        col = vectorProjection(p, sp, ep, vec3(0.3, 0.9, 0.1), col);
    }

    return col;
}

vec3 drawPerpendicular(in vec2 p, in vec3 col) {

    vec4 line1 = vec4(1., -3., 8., -5.);
    vec2 pos = vec2(4., -2.);

    float w = fwidth(p.x);

    col = drawSegment(p, line1.xy, line1.zw, fwidth(p.x) * 2., vec3(1., 0.4, 0.), col);

    vec2 v1 = line1.zw - line1.xy;
    {
        vec2 a = pos - line1.xy;
        float theta = dot(v1, a) / pow(length(v1), 2.);
        vec2 ep = line1.xy + (v1) * theta;

        col = drawSegment(p, ep, pos, w * 1., vec3(0.245, 0.78, 1.), col);
        col = drawPoint(p, pos, fwidth(p.x) * 5., vec3(0.98, 0, 0.49), col);
    }
    if(iMouse.z > 0.001) {
        vec2 m = fixuv(iMouse.xy);
        pos = m;
        vec2 a = pos - line1.xy;
        float theta = dot(v1, a) / pow(length(v1), 2.);
        vec2 ep = line1.xy + (v1) * theta;
        col = drawPoint(p, line1.xy + (v1) * theta, fwidth(p.x) * 5., vec3(0.98, 0, 0.49), col);
        col = drawSegment(p, line1.xy + (v1) * theta, line1.xy, w * 1., vec3(0, 0.19, 0.2), col);
        col = drawSegment(p, ep, pos, w * 1., vec3(0.245, 0.78, 1.), col);
        col = drawSegment(p, line1.xy, pos, w * 1., vec3(0.15, 0, 0.49), col);
        col = drawPoint(p, pos, fwidth(p.x) * 5., vec3(0.98, 0, 0.49), col);
    }

    return col;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec3 col;
    vec2 p = fixuv(fragCoord);
    col = drawGrid(p);
    //画线
    col = drawSegment(p, vec2(-1., 1.), vec2(-5., 6.), fwidth(p.x) * 1., vec3(1., 0., 0.), col);
    col = vectorAdd(p, col);
    col = drawPerpendicular(p, col);
    col = vectorMultiply(p, col);
    fragColor = vec4(col, 1.);
}